<?php
/**
 * Created by PhpStorm.
 * User: 87976
 * Date: 2018/1/10
 * Time: 10:47
 */

namespace App\Services\Orders;

use App\Events\EventAutoOrderCancel;
use App\Events\EventCancelConsignmentNote;
use App\Events\EventOrderStatus;
use App\Events\EventPayStatus;
use App\Events\EventShippingStatus;
use App\Repositories\Goods\GoodsRepository;
use App\Repositories\Order\OrderActionRepository;
use App\Repositories\Order\OrderGoodsRepository;
use App\Repositories\Order\OrderInfoRepository;
use App\Repositories\PayLog\PayLogRepository;
use App\Repositories\Users\UsersRepository;
use App\Services\Goods\GoodsService;
use App\Services\SortingWeb\ToolService;
use Illuminate\Support\Facades\DB;

/**
 * Class PromoteService
 * @package App\Services
 */
class OrderService
{

    /**
     * @var GoodsRepository
     */
    protected $goodsRepository;

    /**
     * @var
     */
    protected $promoteGoods;

    /**
     * @var UserRepository
     */
    protected $usersRepository;

    /**
     * @var OrderInfoRepository
     */
    protected $orderGoodsRepository;

    /**
     * @var OrderInfoRepository
     */
    protected $orderInfoRepository;

    /**
     * @var OrderActionRepository
     */
    protected $orderActionRepository;

    /**
     * @var PayLogRepository
     */
    protected $payLogRepository;


    /**
     * @var GoodsService
     */
    protected $goodsService;    //商品服务
    /**
     * @var array
     */
    protected $integer_type = [
        'tinyint',
        'int',
        'mediumint',
        'bigint',
        'integer',
        'smallint',
        'double',
        'float',
        'decimal',
        'boolean'
    ];
    /**
     * @var array
     */
    protected $error = [];

    /**
     * OrderService constructor.
     * @param OrderInfoRepository $orderInfoRepository
     * @param GoodsRepository $goodsRepository
     * @param UsersRepository $usersRepository
     * @param OrderGoodsRepository $orderGoodsRepository
     * @param PayLogRepository $payLogRepository
     * @param GoodsService $goodsService
     */
    public function __construct(OrderInfoRepository $orderInfoRepository,
                                GoodsRepository $goodsRepository,
                                UsersRepository $usersRepository,
                                OrderGoodsRepository $orderGoodsRepository,
                                PayLogRepository $payLogRepository,
                                OrderActionRepository $orderActionRepository,
                                GoodsService $goodsService)
    {
        $this->goodsRepository = $goodsRepository;
        $this->usersRepository = $usersRepository;
        $this->orderGoodsRepository = $orderGoodsRepository;
        $this->orderInfoRepository = $orderInfoRepository;
        $this->payLogRepository = $payLogRepository;
        $this->orderActionRepository = $orderActionRepository;
        $this->goodsService = $goodsService;//订单商品


    }

    /**
     * 获取所有订单，带分页
     * @param int $page_size
     * @return mixed
     */
    public function getAllOrders(int $page_size){
        return $this->orderInfoRepository->getAll($page_size);
    }

    /**
     * 获取用户订单
     * @param $user_id
     * @param $page_size
     * @return mixed
     */
    public function getOrdersByUserId($user_id,$page_size){
        return $this->orderInfoRepository->getOrdersByUserId($user_id,$page_size);
    }

    /**
     * 获取订单信息
     * @param $orderId
     * @param $columns
     * @return mixed
     */
    public function getOrderById($orderId, $columns=['*']){
        return $this->orderInfoRepository->getOrderInfoById($orderId,$columns);
    }

    /**
     * 获取订单中的商品信息
     * @author yangzhic
     * @param $orderId
     * @return mixed
     */
    public function getGoodsList($orderId){
        return $this->orderGoodsRepository->getGoodsList($orderId);
    }

    /**
     * 更新订单状态(order_status)
     * @param int $order_id 订单ID;
     * @param $order_status 订单状态;
     * @param int $user_type 操作用户类型: 0系统; 1管理人员; 2用户;
     * @param int $show4user 是否显示给用户, 1显示, 0不显示;
     * @return bool
     * @author ^2_3^岑业宝
     */
    public function updateOrderStatus($order_id = 0, $order_status, $user_type=0, $show4user=0) {
        $flag = false;

        /// 参数验证
        if( empty($order_id) || !isset($order_status) ) {
            return $flag;
        }

        /// 验证状态是否存在
        $a_order_status = config('custom.order_status');
        $c_order_status = collect( $a_order_status );
        if( !$c_order_status->has($order_status) ) {
            return $flag;
        }

        /// 订单状态修改
        $flag = $this->orderInfoRepository->updateOrderStatus($order_id, $order_status);
        //-/ 分发订单状态改变事件
        if( $flag && $flag !== true ) {
            $m_order_u = $flag;
            $m_order_u->user_type = $user_type;
            $m_order_u->show4user = $show4user;
            event(new EventOrderStatus($m_order_u));

            $flag = true;
        }

        return $flag;
    }

    /**
     * 更新支付状态(pay_status)
     * @param int $order_id 订单ID;
     * @param $pay_status 支付状态;
     * @param int $user_type 操作用户类型: 0系统; 1管理人员; 2用户;
     * @param int $show4user 是否显示给用户, 1显示, 0不显示;
     * @return bool
     * @author ^2_3^岑业宝
     */
    public function updatePayStatus($order_id = 0, $pay_status, $user_type=0, $show4user=0) {
        $flag = false;

        /// 参数验证
        if( empty($order_id) || !isset($pay_status) ) {
            return $flag;
        }

        /// 验证状态是否存在
        $a_pay_status = config('custom.pay_status');
        $c_pay_status = collect( $a_pay_status );
        if( !$c_pay_status->has($pay_status) ) {
            return $flag;
        }

        /// 支付状态修改
        $flag = $this->orderInfoRepository->updatePayStatus($order_id, $pay_status);
        //-/ 分发支付状态变动事件
        if( $flag && $flag !== true ) {
            $m_pay_u = $flag;
            $m_pay_u->user_type = $user_type;
            $m_pay_u->show4user = $show4user;
            event(new EventPayStatus($m_pay_u));

            $flag = true;
        }

        return $flag;
    }

    /**
     * 更新发货状态(shipping_status)
     * @param int $order_id 订单ID;
     * @param $shipping_status 发货状态;
     * @param int $user_type 操作用户类型: 0系统; 1管理人员; 2用户;
     * @param int $show4user 是否显示给用户, 1显示, 0不显示;
     * @return bool
     * @author ^2_3^岑业宝
     */
    public function updateShippingStatus($order_id = 0, $shipping_status, $user_type=0, $show4user=0) {
        $flag = false;

        /// 参数验证
        if( empty($order_id) || !isset($shipping_status) ) {
            return $flag;
        }

        /// 验证状态是否存在
        $a_ship_status = config('custom.shipping_status');
        $c_ship_status = collect( $a_ship_status );
        if( !$c_ship_status->has($shipping_status) ) {
            return $flag;
        }

        /// 发货状态修改
        $flag = $this->orderInfoRepository->updateShippingStatus($order_id, $shipping_status);
        //-/ 分发发货状态变动事件
        if( $flag && $flag !== true ) {
            $m_ship_u = $flag;
            $m_ship_u->user_type = $user_type;
            $m_ship_u->show4user = $show4user;
            event(new EventShippingStatus($m_ship_u));

            $flag = true;
        }

        return $flag;
    }

    /**
     * 保存订单
     * @author yangzhic
     * @param $orders = ['order_info'=>[],'goods_list'=>[],pay_log=>[]]
     * @return bool
     * @throws \Exception
     */
    public function save($orders)
    {
        DB::beginTransaction();

        //=========处理订单保存=========
        //保存订单信息
        $orderId = $this->saveOrder($orders['order_info']);

        if($orderId){
            //保存订单商品信息
            $flag = $this->addOrderGoods($orderId,$orders['goods_list']);
        }else{
            $flag = false;
        }

        if($flag){
            //添加订单支付记录
            $flag = $this->addPayLog($orders['pay_log']);
        }

        if($flag){
            DB::commit();
            //事件处理
        }else{
            DB::rollBack();
        }

        return $flag;
    }

    /**
     * @author yangzhic
     * @return string
     */
    public function getOrderSn()
    {
        return get_order_sn();
    }


    /**
     * @author yangzhic
     * @param array $order
     * @return array
     */
    public function orderInfoFormat(array $order)
    {
        $orderData = [];

        $tableColumns = $this->orderInfoRepository->getOrderInfoColumns();

        foreach($tableColumns as $key=>$val){
            if(!empty($order[$val])){
                $orderData[$val] = $order[$val];
            }

        }
        //过滤主键
        unset($orderData['order_id']);

        return $orderData;
    }

    /**
     * 新增订单信息
     * @author yangzhic
     * @param array $data
     * @param bool $format
     * @return mixed
     */
    public function saveOrder(array $data,$format = false)
    {
        if($format){
            $orderData = $this->orderInfoFormat($data);
        }else{
            $orderData = $data;
        }

        return $this->orderInfoRepository->saveOrder($orderData);
    }

    /**
     * @author yangzhic
     * @param int $orderId
     * @param array $goodsList
     * @return array
     */
    public function orderGoodsFormat(int $orderId,array $goodsList)
    {
        $order_goods_list = [];
        $tableColumns = $this->orderInfoRepository->getOrderGoodsColumns();

        foreach($goodsList as $key=>$item){
            $goods = [];
            foreach($tableColumns as $column_name){
                if(!empty($item[$column_name])){
                    $goods[$column_name] = $item[$column_name];
                }
            }
            $goods['order_id'] = $orderId;
            //过滤主键
            unset($goods['rec_id']);

            $order_goods_list[] = $goods;
        }

        return $order_goods_list;
    }

    /**
     * 保存订单商品信息
     * @author yangzhic
     * @param int $orderId
     * @param array $goodsList
     * @param bool $format
     * @return bool
     */
    public function addOrderGoods(int $orderId,array $goodsList,$format = false)
    {
        if($format){
            $orderGoodsList = $this->orderGoodsFormat($orderId,$goodsList);
        }else{
            $orderGoodsList =  $goodsList;
        }
        if(!empty($orderGoodsList)){
            return $this->orderGoodsRepository->batchInsert($orderGoodsList);
        }else{
            return false;
        }
    }

    /**
     * 生成订单支付记录
     * @author yangzhic
     * @param array $data
     * @return mixed
     */
    public function addPayLog(array $data)
    {
        return $this->payLogRepository->addPayLog($data);
    }

    /**
     * 修改订单支付记录
     * @author yangzhic
     * @param $pay_log_id
     * @param array $data
     * @return mixed
     */
    public function changePayLog($pay_log_id,array $data){
        return $this->payLogRepository->updatePayLog($pay_log_id,$data);
    }


    /**
     * 订单结算 商品预售/现售 分组列表
     * @author yangzhic
     * @param $cart_goods_list
     * @param bool $need_convert
     * @return array
     */
    public function getCartGoodsGroupList($cart_goods_list,$need_convert=true){
        if($need_convert){
            $goods_list = $this->getCartGoodsList($cart_goods_list);
        }else{
            $goods_list = $cart_goods_list;
        }

        $cart_goods_list_group = array();
        $cart_goods_pre_sell_group = array();    //预售商品
        $cart_goods_sell_group = array();   //现售商品
        $temp_pre_sell = array();
        foreach($goods_list as $key=>$goods){
            if($goods['is_presell']==1 && !empty($goods['preselltimeres']['delivery_time'])){
                $predate = date('Y-m-d',strtotime($goods['preselltimeres']['delivery_time']));
                $sort_key = strtotime($predate);
                if(!in_array($sort_key,$temp_pre_sell)){
                    $temp_pre_sell[] = strtotime($predate);
                    $cart_goods_pre_sell_group[$sort_key]['shipping_date'] = $predate;
                }
                $cart_goods_pre_sell_group[$sort_key]['goods_list'][] = $goods;
            }else{
                $cart_goods_sell_group[] = $goods;
            }
        }
        krsort($cart_goods_pre_sell_group,SORT_NUMERIC);
        if(!empty($cart_goods_pre_sell_group)){
            foreach($cart_goods_pre_sell_group as $key=>$val){
                $cart_goods_pre_sell_group[$key]['goods_num'] = count($cart_goods_pre_sell_group[$key]['goods_list']);
            }
            $cart_goods_list_group['has_pre_sell'] = 1;
        }else{
            $cart_goods_list_group['has_pre_sell'] = 0;
        }
        $cart_goods_pre_sell_group = array_values($cart_goods_pre_sell_group);
        $cart_goods_list_group['pre_sell'] = $cart_goods_pre_sell_group;

        $cart_goods_list_group['sell']['goods_list'] = $cart_goods_sell_group;
        $cart_goods_list_group['sell']['goods_num'] = count($cart_goods_sell_group);

        $cart_goods_list_group['goods_total_number'] = count($goods_list);

        return $cart_goods_list_group;
    }

    /**
     *组合购物车商品
     * @author yangzhic
     * @param $cart_goods_list
     * @return array
     */
    public function getCartGoodsList($cart_goods_list){
        $goods_list = array();
        //合并购物车商品
        if(!empty($cart_goods_list['favourable_goods'])){
            foreach($cart_goods_list['favourable_goods'] as $f_key=>$f_val){
                if(!empty($f_val['goods_list'])){
                    foreach($f_val['goods_list'] as $fg_key=>$fg_val){
                        $goods_list[] = $fg_val;
                    }
                }
            }
        }

        if(!empty($cart_goods_list['normal_goods'])){
            foreach($cart_goods_list['normal_goods'] as $normal_key=>$normal_val){
                $goods_list[] = $normal_val;
            }
        }

        return $goods_list;
    }

    /**
     * 计算订单重量
     * Author:poptser@foxmail.com
     * @param int $orderId
     * @return bool|float|int
     */
    public function getOrderWeight(int $orderId){
        $goodsList = $this->getOrderGoodsListExisting($orderId);
        if(!empty($goodsList)){
            $orderWeight = 0;
            foreach ($goodsList as $value){
                $orderWeight +=
                    $this->goodsService->getGoodsWeight($value['goods_id']) *
                    $value['goods_number'];
            }
            return $orderWeight;
        }else{
            return false;
        }
    }


    /**
     * 获取商品列表[ 排除已退款 ]
     * Author:poptser@foxmail.com
     * @param int $orderId
     * @return bool
     */
    public function getOrderGoodsListExisting(int $orderId){
        $orderGoodsList = $this->getGoodsList($orderId);
        if($orderGoodsList){
            foreach ($orderGoodsList as $key=>$value){
                if($value['goods_number'] == $value['refund_number']){
                    //删除已退完的商品
                    unset($orderGoodsList[$key]);
                }
            }
            return $orderGoodsList;
        }else{
            return false;
        }
    }

    /**
     * 添加订单记录
     * @author yangzhic
     * @param $param
     * @return mixed
     */
    public function addOrderAction($param){
        return $this->orderActionRepository->addOrderAction($param);
    }

    /**
     * @return mixed
     */
    public function get38data(){
        return $this->orderInfoRepository->get38data();
    }


    /**
     * 检查取消订单释放符合条件
     * @param $order_id
     * @return mixed
     */
    public function CheckOrderCancelEligible($order_id){
        return $this->orderInfoRepository->CheckOrderCancelEligible($order_id);
    }

    /**
     * 更新取消订单状态以及订单支付备注
    */
    public function UpdateOrderStatusAndPayNote($order_id){
        $upreturn= $this->orderInfoRepository->UpdateOrderStatusAndPayNote($order_id);
        if($upreturn){
            $orderinfo= $this->orderInfoRepository->getOrderInfoById($order_id,['order_status','shipping_status','pay_status']);
            $data['order_status'] = $orderinfo->order_status;
            $data['shipping_status'] = $orderinfo->shipping_status;
            $data['pay_status'] = $orderinfo->pay_status;
            $data['action_user'] = '订单取消-自动脚本';
            $data['order_id']=$order_id;
            $data['action_note']="订单超时自动取消";
            $data['log_time']=gm_time();
            $this->orderActionRepository->addOrderAction($data);
        }
        return $upreturn;
    }

    /***
     * 更新用户手动取消订单状态以及订单支付备注
     * @param $order_id
     * @param $user_id
    @author echa
     * @return mixed
     */
    public function UpdateUsersOrderStatusAndPayNote($order_id,$user_id){
        $upreturn= $this->orderInfoRepository->UpdateUsersOrderStatusAndPayNote($order_id,$user_id);
        if($upreturn){
            $orderinfo= $this->orderInfoRepository->getOrderInfoById($order_id,['order_status','shipping_status','pay_status']);
            $data['order_status'] = $orderinfo->order_status;
            $data['shipping_status'] = $orderinfo->shipping_status;
            $data['pay_status'] = $orderinfo->pay_status;
            $data['action_user'] = 'buyer';
            $data['order_id']=$order_id;
            $data['action_note']="手动取消订单";
            $data['log_time']=gm_time();
            $this->orderActionRepository->addOrderAction($data);
        }
        return $upreturn;
    }

    /**
    *  订单自动取消
     */
    public function auto_order_cancel(array $order){
        $order_id=$order['order_id'];
        $flas=$this->orderInfoRepository->CheckOrderCancelEligible($order_id);
        if($flas){
            $return=$this->UpdateOrderStatusAndPayNote($order_id);
            if($return){
                $this->orderInfoRepository->UpdateUsedTimeAndOrder($order_id);
                $this->orderInfoRepository->UpdateOrderCancelInitialize($order_id);
                $this->orderInfoRepository->DeleteActivityQuota($order_id);
                $this->orderInfoRepository->OperationBonusfreight($order_id);
                event(new EventCancelConsignmentNote($order));
            }
        }else{
            return false;
        }
    }

    /***
     * 用户手动取消
     * @param $order_id
     * @param $user_id
    @author echa
     * @return bool
     */
    public function users_hand_order_cancel(array $order){
        $order_id=$order['order_id'];
        $user_id=$order['user_id'];
        $upfals=$this->UpdateUsersOrderStatusAndPayNote($order_id,$user_id);
        if($upfals){
            $this->orderInfoRepository->UpdateUsedTimeAndOrder($order_id,$user_id);
            $this->orderInfoRepository->UpdateOrderCancelInitialize($order_id,$user_id);
            $this->orderInfoRepository->DeleteActivityQuota($order_id);
            $this->orderInfoRepository->OperationBonusfreight($order_id,$user_id);
            event(new EventCancelConsignmentNote($order));
            return true;
        }else{
            return false;
        }
    }

    /**
     *  执行订单自动取消
     * @param  $order_id
     */
    public function ExecuteAutoOrderCancel($order_id){
        $orderinfo= $this->orderInfoRepository->getOrderInfoById($order_id,['order_id','order_sn','k3cn_sn','order_status','pay_status','shipping_status']);
        if($orderinfo){
            $order_status=$orderinfo->order_status;
            $shipping_status=$orderinfo->shipping_status;
            $pay_status=$orderinfo->pay_status;
            if($order_status==2){  // 已经取消
                return false;
            }
            if($shipping_status>0){  // 已经发货中
                return false;
            }
            if($order_status==0 && $pay_status==0){
                $orderdata=[
                    'order_id'=>$orderinfo->order_id,
                    'order_sn'=>$orderinfo->order_sn,
                    'k3cn_sn'=>$orderinfo->k3cn_sn,
                ];
                event(new EventAutoOrderCancel($orderdata));
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

    public function ExecuteUsersHandOrderCancel($order_id,$user_id){
        $orderinfo= $this->orderInfoRepository->getOrderInfoById($order_id,['order_id','order_sn','user_id','k3cn_sn','order_status','pay_status','shipping_status']);
        if($orderinfo){
            $ouser_id=$orderinfo->user_id;
            $order_status=$orderinfo->order_status;
            $shipping_status=$orderinfo->shipping_status;
            $pay_status=$orderinfo->pay_status;
            if($ouser_id!=$user_id){
                return false;
            }
            if($order_status==2){  // 已经取消
                return false;
            }
            if($shipping_status>0){  // 已经发货中
                return false;
            }
            $orderdata=[
                'order_id'=>$orderinfo->order_id,
                'order_sn'=>$orderinfo->order_sn,
                'k3cn_sn'=>$orderinfo->k3cn_sn,
                'user_id'=>$ouser_id
            ];
            if($order_status==0 && $pay_status==0){
                return $this->users_hand_order_cancel($orderdata);
            }elseif($order_status>0 && $order_status!=2 && $pay_status!=4 && $pay_status>1 && $shipping_status==0){
                event(new EventCancelConsignmentNote($orderdata)); //未处理用户退款操作和修改订单取消状态操作
                return true;
            }else{
                return false;
            }

        }else{
            return false;
        }
    }

    /***
     * @param $order_id
     * @param $cn_sn
    @author echa
     * @return mixed
     */
    public function UpdateOrderk3cn_sn($order_id,$cn_sn){
        return $this->orderInfoRepository->UpdateOrderk3cn_sn($order_id,$cn_sn);
    }




}